package com.inspectortime.webapp.payment;

import java.text.SimpleDateFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.inspectortime.domain.Inspection;
import com.inspectortime.domain.Inspector;
import com.inspectortime.domain.InspectorCompany;
import com.inspectortime.domain.billing.ConfirmedStatus;
import com.inspectortime.domain.billing.Invoice;
import com.inspectortime.domain.billing.Payment;
import com.inspectortime.domain.billing.PaymentLineItem;
import com.inspectortime.domain.billing.PaymentMethod;
import com.inspectortime.domain.billing.PaymentSourceType;
import com.inspectortime.domain.type.PaymentStatus;
import com.inspectortime.domain.type.State;
import com.inspectortime.repository.Repository;
import com.mkode.util.servlet.RequestDebugger;

/**
 * Controller for a form POST callback from Paypal. Note this URL is configured
 * by the notify_url parameter on paypal post requests
 * 
 * @author mkvalsvik
 * 
 */
public class PayPalConfirmationCallbackResponseController extends AbstractConfirmationCallbackResponseController {

	private static Log log = LogFactory
			.getLog(PayPalConfirmationCallbackResponseController.class);

	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		log.debug("Processing callback request...");

		if (!request.getMethod().equalsIgnoreCase("post")) {
			log.warn("Not a POST request: \n"
					+ RequestDebugger.requestToString(request));
			return showDefaultError();
		}

		String invoiceNumber = request.getParameter("item_number");
		if (invoiceNumber == null) {
			log.warn("Missing parameter 'item_number': \n"
					+ RequestDebugger.requestToString(request));
			return showDefaultError();
		}

		Payment payment = repository.findPaymentByInvoiceNumber(invoiceNumber);
		if (payment == null) {
			log.warn("Invoice number '" + invoiceNumber
					+ "' does not exist: \n"
					+ RequestDebugger.requestToString(request));
			return showDefaultError();
		}

		// Bind request data to payment instance
		payment.setAmount(Double.parseDouble(request.getParameter("payment_gross")));
		payment.getPayerName().setFirst(request.getParameter("first_name"));
		payment.getPayerName().setLast(request.getParameter("last_name"));
		payment.getPayerAddress().setStreet1(request.getParameter("address_street"));
		payment.getPayerAddress().setCity(request.getParameter("address_city"));
		payment.getPayerAddress().setState(State.valueOf(request.getParameter("address_state")));
		payment.getPayerAddress().setZipCode(request.getParameter("address_zip"));
		payment.setPayerEmail(request.getParameter("payer_email"));
		payment.setTransactionId(request.getParameter("txn_id"));
		String txnTime = request.getParameter("payment_date");
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss MMM dd, yyyy z");
		payment.setTransactionTime(sdf.parse(txnTime));
		String responseCode = request.getParameter("payment_status");
		payment.setResponseCode(responseCode);
		if (responseCode.equalsIgnoreCase("Completed")) {
			payment.setConfirmedStatus(ConfirmedStatus.CONFIRMED);
			updatePaymentSourceStatus(payment, PaymentStatus.PAID_PAYPAL);
		} else {
			payment.setConfirmedStatus(ConfirmedStatus.DECLINED);
			updatePaymentSourceStatus(payment, PaymentStatus.NOT_PAID);
		}
		payment.setPaymentMethod(PaymentMethod.PAYPAL);
		payment.save();

		InspectorCompany company = this.lookupCompany(payment);
		

		// Render view
		ModelAndView mv = new ModelAndView(
				"payment/processorConfirmationCallbackResponse");
		mv.addObject("inspectorCompany", company);
		mv.addObject("payment", payment);
		return mv;
	}
}
